<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>call bind apply</title>
</head>
<script>
    (function () {
        var a = {
            name: '阿姨请别把您闺女介绍给我',
            sex: '男',
            age: '24',
            say: function () {
                console.log(this.name + ',今年' + this.age + '岁，性别' + this.sex)
            }
        }

        var b = {
            name: '就要把闺女介绍给你',
            sex: '女',
            age: '18'
        }

        a.say();//阿姨请别把您闺女介绍给我,今年24岁了，性别男

        a.say.call(b)
        a.say.apply(b)
        a.say.bind(b)();
    });

    (function () {
        var a = {
            name: '阿姨请不要把您闺女介绍给我',
            sex: '男',
            age: '18',
            say: function (school, grade) {
                console.log(this.name + '性别' + this.sex + '年龄, ' + this.age + school + grade)
            }
        }

        var b = {
            name: '就喜欢把闺女介绍给你',
            sex: '女',
            age: '18'
        }

        a.say('南开', '一年级');
        a.say.call(b, '清华', '三年级');

        a.say.apply(b, ['清华', '六年级']);


        a.say.bind(b, '清华', '三年级');

        a.say.bind(b)('清华', '三年级');
    });

    (function () {
        function Shape(x, y) {
            this.x = x;
            this.y = y;
        }

        var a = {};
        Shape.call(a, 1, 2);
        console.log(a);
        Shape.apply(a, [21, 42]);
        console.log(a);

    }());

    (function () {
        'use strict';
        console.log('=== 测试this === ');
        console.log(this);

        function MyObject() {
            const _self = this;
            return {
                x: 1,
                y: 2,
                add: function () {
                    console.log([this.x, this.y]);
                },
                add2: function () {
                    return () => {
                        console.log(this);
                    };
                }
            }
        }
        var a = { a: 1 }
        let _this = MyObject();
        _this.add();
        _this.add2()();
    }());

    (function () {
        var foo = { x: 10 };
        var bar = {
            x: 20,
            test: function () {
                console.log(this);
                console.log(this.x);
            }
        };

        bar.test();
        foo.test = bar.test;
        foo.test();
    }());

    (function () {
        function foo() {
            console.log(this);
        }
        foo();  //global
        foo.prototype.constructor(); // foo
        var a = new foo();
    }());

    function aaa(self) {
        console.log(self);
        return () => {
            console.log('a');
            console.log(self);
        }
    }

    (function () {
        function Thing1() {
            this.foo = "foo";
        }
        Thing1.prototype.foo = "bar";

        function Thing2() {
            this.logFoo();
            Thing1.apply(this);
            this.logFoo();
        }
        Thing2.prototype = Object.create(Thing1.prototype);
        Thing2.prototype.logFoo = function () {
            console.log(this.foo);
        }

        var thing = new Thing2();
    }());

    (function () {
        function Thing() {
        }
        Thing.prototype.foo = "bar";
        Thing.prototype.logFoo = function () {
            console.log(this.foo);
        }
        Thing.prototype.setFoo = function (newFoo) {
            this.foo = newFoo;
        }

        var thing1 = new Thing();
        var thing2 = new Thing();

        console.log('1...');
        thing1.logFoo(); //logs "bar"
        thing2.logFoo(); //logs "bar"

        thing1.setFoo("foo");
        thing1.logFoo(); //logs "foo";
        thing2.logFoo(); //logs "bar";

        thing2.foo = "foobar";
        thing1.logFoo(); //logs "foo";
        thing2.logFoo(); //logs "foobar";

        delete thing1.foo;
        thing1.logFoo(); //logs "bar";
    }());

    (function () {
        function Thing() {
        }
        Thing.prototype.things = [];


        var thing1 = new Thing();
        var thing2 = new Thing();
        thing1.things.push("foo");
        console.log(thing2.things); //logs ["foo"]
    }());
</script>
<style>
    #foo {

        width: 100px;
        height: 100px;
        background: salmon;
    }
</style>

<body>
    <div id="foo" onclick="aaa(this)();"></div>
</body>

</html>